const axios = require('axios')
const randomstring = require('randomstring')
const querystring = require('querystring')
const crypto = require('crypto')
const convert = require('xml-js')
const QRCode = require('qrcode')
 
QRCode.toDataURL('I am a pony!', function (err, url) {
  console.log(url)
})

const { orderUrl, appid, mch_id, notify_url, key } = require('../config/config')

function genSignature(_prepay) {
  const sortedPrepay = Object.keys(_prepay).sort().reduce((obj, key) => {
    obj[key] = _prepay[key]
    return obj
  }, {})

  const stringA = querystring.stringify(sortedPrepay, null, null, {
    encodeURIComponent(string) {
      return string
    }
  })
  const stringSignTemp = stringA + '&key=' + key
  const signValue = crypto.createHash('md5').update(stringSignTemp).digest('hex').toUpperCase()
  return signValue
}

function genQrcode(code_url) {
  return new Promise((resolve, reject) => {
    QRCode.toDataURL(code_url, function (err, url) {
      resolve(url)
    })
  })
}

const pay = async (ctx, next) => {

  // 获取订单号、订单金额及商品描述
  let { out_trade_no, total_fee, body } = ctx.request.body

  // nonce_str
  const nonce_str = randomstring.generate(32)

  
  // trade_type
  const trade_type = 'NATIVE'

  const _prepay = {
    appid,
    mch_id,
    nonce_str,
    body,
    out_trade_no,
    total_fee: parseInt(total_fee),
    notify_url,
    trade_type
  }
  
  // sign
  const sign = genSignature(_prepay)
  const prepay = {
    xml: {
      ..._prepay,
      sign
    }
  }

  const xml = convert.js2xml(prepay, {
    compact: true
  })

  // 调用统一下单API
  let result = await axios.post(orderUrl, xml)
  
  // 转化结果
  let code_url = convert.xml2js(result.data, {
    compact: true,
    cdataKey: 'value',
    textKey: 'value'
  }).xml.code_url.value
 
  let imgsrc = await genQrcode(code_url)

  await ctx.render('succ', {
    imgsrc
  })
}

const notify = async (ctx, next) => {
  ctx.body = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'
}


module.exports = {
  pay,
  notify
}